package im

import (
	"context"
	"fmt"
	"github.com/flipped-aurora/gin-vue-admin/server/global"
	_const "github.com/flipped-aurora/gin-vue-admin/server/global/const"
	"github.com/flipped-aurora/gin-vue-admin/server/model/im/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/im/response"
	http_request "github.com/flipped-aurora/gin-vue-admin/server/utils/request"
	"github.com/mitchellh/mapstructure"
	"github.com/pkg/errors"
	"go.uber.org/zap"
	"strconv"
	"time"
)

// IMUserService openim-server用户模块
type IMUserService struct{}

var IMUserServiceApp = new(IMUserService)

// RegisterUsers 将新注册的用户同步到openim；注册时调用
func (i IMUserService) RegisterUsers(ctx context.Context, users []request.IMUser) error {
	var registerURL = _const.OpenImServerAddress + "/user/user_register"
	var reqData = request.IMUserRegisterRequest{
		Users: users,
	}
	// 从缓存中获取adminToken
	adminToken, errToken := global.IMAdminTokenCache.Get(ctx)
	if errToken != nil {
		global.GVA_LOG.Error("openim 同步失败!", zap.Error(errToken))
		return fmt.Errorf("failed get token cache: %w", errToken)
	}

	var headers = make(map[string]string, 1)
	headers[request.OpenIMOperationIDHeader] = strconv.Itoa(time.Now().Second())
	headers[request.OpenIMTokenHeader] = adminToken.(string)
	var openImResp = response.OpenImResponse{}
	var _, errReq = http_request.HttpRequest(registerURL, http_request.POST, headers, http_request.EmptyParams, reqData, &openImResp)
	if errReq != nil {
		global.GVA_LOG.Error("openim 请求失败!", zap.Error(errToken))
		return errReq
	}

	if openImResp.ErrCode != 0 {
		global.GVA_LOG.Error("openim 请求结果!",
			zap.Int("err_code", openImResp.ErrCode),
			zap.String("err_dlt", openImResp.ErrDlt))

		return errors.Errorf("unexpected openim code %s, err_dlt: %s",
			openImResp.ErrCode, openImResp.ErrDlt)
	}

	return nil
}

// UpdateUserInfo 修改用户信息
func (i IMUserService) UpdateUserInfo(ctx context.Context, user request.IMUser) error {
	var updateURL = _const.OpenImServerAddress + "/user/update_user_info_ex"
	var reqData = request.IMUpdateUserRequest{
		UserInfo: user,
	}
	// 从缓存中获取adminToken
	adminToken, errToken := global.IMAdminTokenCache.Get(ctx)
	if errToken != nil {
		return fmt.Errorf("failed get token cache: %w", errToken)
	}

	var headers = make(map[string]string, 1)
	headers[request.OpenIMOperationIDHeader] = strconv.Itoa(time.Now().Second())
	headers[request.OpenIMTokenHeader] = adminToken.(string)

	var openImResp = response.OpenImResponse{}
	var _, errReq = http_request.HttpRequest(updateURL, http_request.POST, headers, http_request.EmptyParams, reqData, &openImResp)
	if errReq != nil {
		global.GVA_LOG.Error("open_im请求失败!",
			zap.String("url", "/user/update_user_info_ex"),
			zap.Error(errReq))
		return errReq
	}

	if openImResp.ErrCode != 0 {
		global.GVA_LOG.Error("open_im请求出错!",
			zap.String("url", "/user/update_user_info_ex"),
			zap.Int("err_code", openImResp.ErrCode),
			zap.String("err_dlt", openImResp.ErrDlt))
		return errors.Errorf("unexpected openim code %d, err_dlt: %s",
			openImResp.ErrCode, openImResp.ErrDlt)
	}

	return nil
}

// GetAllUsersPagination 分页查询已注册用户的userID列表
func (i IMUserService) GetAllUsersPagination(ctx context.Context, usersRequest request.IMGetAllUsersRequest) (response.UserIDsResponseData, error) {
	var queryURL = _const.OpenImServerAddress + "/user/get_all_users_uid"

	var data = response.UserIDsResponseData{}

	// 从缓存中获取adminToken
	adminToken, errToken := global.IMAdminTokenCache.Get(ctx)
	if errToken != nil {
		return data, fmt.Errorf("failed get token cache: %w", errToken)
	}

	var headers = make(map[string]string, 1)
	headers[request.OpenIMOperationIDHeader] = strconv.Itoa(time.Now().Second())
	headers[request.OpenIMTokenHeader] = adminToken.(string)
	var openImResp = response.OpenImResponse{}
	var _, errReq = http_request.HttpRequest(queryURL, http_request.POST, headers, http_request.EmptyParams, usersRequest, &openImResp)
	if errReq != nil {
		return data, errReq
	}

	if openImResp.ErrCode != 0 {
		return data, errors.Errorf("unexpected openim code %d, err_dlt: %s",
			openImResp.ErrCode, openImResp.ErrDlt)
	}

	if err := mapstructure.Decode(openImResp.Data, &data); err != nil {
		return data, errors.Errorf("get_all_users_uid mapstruct failed! %w, raw_data=%v",
			err, openImResp.Data)
	}

	return data, nil
}
